"""
态势对象 API 路由
"""
from typing import List, Optional, Dict
from uuid import UUID
from datetime import datetime
from fastapi import APIRouter, Depends, HTTPException, Body, Query
from sqlalchemy.ext.asyncio import AsyncSession

from src.situation.database import get_db
from src.situation.service import SituationService
from src.situation.schemas import (
    SituationObjectCreate,
    SituationObjectUpdate,
    SituationObjectResponse,
    SituationObjectListResponse,
    SituationObjectFilter,
    ObjectType,
    DeploymentStatus,
    ImportRequest,
    StatisticsResponse,
    EquipmentCategoryResponse,
    EquipmentCategoriesListResponse,
)
from server.utils.auth_middleware import get_required_user, get_admin_user
from server.models.user_model import User
from src.utils import logger

situation = APIRouter(prefix="/situation", tags=["situation"])


# ============================================================================
# === 态势对象 CRUD ===
# ============================================================================


@situation.post("/objects", response_model=SituationObjectResponse)
async def create_situation_object(obj_data: SituationObjectCreate, db: AsyncSession = Depends(get_db), current_user: User = Depends(get_admin_user)):
    """创建态势对象"""
    logger.info(f"[路由调试] 接收到创建态势对象请求: {obj_data.name}")

    try:
        result = await SituationService.create_object(db, obj_data, user=current_user.username if current_user else None)
        logger.info(f"[路由调试] 态势对象创建成功: {result.id}")
        return result
    except ValueError as ve:
        # 业务逻辑错误，返回 400
        logger.warning(f"[路由调试] 创建对象业务逻辑错误: {ve}")
        raise HTTPException(status_code=400, detail=str(ve))
    except Exception as e:
        # 系统错误，返回 500
        logger.error(f"[路由调试] 创建对象系统错误: {type(e).__name__}: {e}")
        import traceback
        logger.error(f"[路由调试] 错误堆栈: {traceback.format_exc()}")
        raise HTTPException(status_code=500, detail=f"系统错误，创建失败: {str(e)}")


@situation.get("/objects", response_model=SituationObjectListResponse)
async def list_situation_objects(
    page: int = Query(1, ge=1, description="页码"),
    page_size: int = Query(20, ge=1, le=100, description="每页数量"),
    object_type: Optional[ObjectType] = Query(None, description="对象类型筛选"),
    deployment_status: Optional[DeploymentStatus] = Query(None, description="部署状态筛选"),
    organization: Optional[str] = Query(None, description="所属单位筛选"),
    search: Optional[str] = Query(None, description="搜索关键字"),
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_required_user),
):
    """获取态势对象列表（支持分页、筛选、搜索）"""
    logger.info(f"[路由调试] 接收到列表查询请求")
    logger.info(f"[路由调试] 请求参数: page={page}, page_size={page_size}, object_type={object_type}, deployment_status={deployment_status}, organization={organization}, search={search}")
    logger.info(f"[路由调试] 当前用户: {current_user.username if current_user else 'None'}")

    try:
        logger.info(f"[路由调试] 开始构建筛选条件")
        filters = SituationObjectFilter(object_type=object_type, deployment_status=deployment_status, organization=organization, search=search)
        logger.info(f"[路由调试] 筛选条件构建完成: {filters}")

        logger.info(f"[路由调试] 开始调用服务层")
        result = await SituationService.list_objects(db, page=page, page_size=page_size, filters=filters)
        logger.info(f"[路由调试] 服务层调用成功，返回结果: total={result.total}, items_count={len(result.items)}")

        return result
    except HTTPException as e:
        logger.error(f"[路由调试] HTTP异常: status_code={e.status_code}, detail={e.detail}")
        raise
    except Exception as e:
        logger.error(f"[路由调试] 未知异常: {type(e).__name__}: {e}")
        import traceback
        logger.error(f"[路由调试] 异常堆栈: {traceback.format_exc()}")
        raise HTTPException(status_code=500, detail=f"查询失败: {str(e)}")


@situation.get("/objects/{object_id}", response_model=SituationObjectResponse)
async def get_situation_object(object_id: UUID, db: AsyncSession = Depends(get_db), current_user: User = Depends(get_required_user)):
    """获取态势对象详情"""
    result = await SituationService.get_object(db, object_id)
    if not result:
        raise HTTPException(status_code=404, detail="对象不存在")
    return result


@situation.put("/objects/{object_id}", response_model=SituationObjectResponse)
async def update_situation_object(object_id: UUID, obj_data: SituationObjectUpdate, db: AsyncSession = Depends(get_db), current_user: User = Depends(get_admin_user)):
    """更新态势对象"""
    logger.info(f"[路由调试] 接收到更新态势对象请求: {object_id}")

    try:
        result = await SituationService.update_object(db, object_id, obj_data, user=current_user.username if current_user else None)
        if not result:
            logger.warning(f"[路由调试] 要更新的对象不存在: {object_id}")
            raise HTTPException(status_code=404, detail="对象不存在")
        logger.info(f"[路由调试] 态势对象更新成功: {result.id}")
        return result
    except ValueError as ve:
        # 业务逻辑错误，返回 400
        logger.warning(f"[路由调试] 更新对象业务逻辑错误: {ve}")
        raise HTTPException(status_code=400, detail=str(ve))
    except HTTPException:
        # 重新抛出 HTTPException（如 404）
        raise
    except Exception as e:
        # 系统错误，返回 500
        logger.error(f"[路由调试] 更新对象系统错误: {type(e).__name__}: {e}")
        import traceback
        logger.error(f"[路由调试] 错误堆栈: {traceback.format_exc()}")
        raise HTTPException(status_code=500, detail=f"系统错误，更新失败: {str(e)}")


@situation.delete("/objects/{object_id}")
async def delete_situation_object(object_id: UUID, db: AsyncSession = Depends(get_db), current_user: User = Depends(get_admin_user)):
    """删除态势对象"""
    logger.info(f"[路由调试] 接收到删除态势对象请求: {object_id}")

    try:
        success = await SituationService.delete_object(db, object_id, user=current_user.username if current_user else None)
        if not success:
            logger.warning(f"[路由调试] 要删除的对象不存在: {object_id}")
            raise HTTPException(status_code=404, detail="对象不存在")
        logger.info(f"[路由调试] 态势对象删除成功: {object_id}")
        return {"message": "删除成功", "id": str(object_id)}
    except ValueError as ve:
        # 业务逻辑错误，返回 400
        logger.warning(f"[路由调试] 删除对象业务逻辑错误: {ve}")
        raise HTTPException(status_code=400, detail=str(ve))
    except HTTPException:
        # 重新抛出 HTTPException（如 404）
        raise
    except Exception as e:
        # 系统错误，返回 500
        logger.error(f"[路由调试] 删除对象系统错误: {type(e).__name__}: {e}")
        import traceback
        logger.error(f"[路由调试] 错误堆栈: {traceback.format_exc()}")
        raise HTTPException(status_code=500, detail=f"系统错误，删除失败: {str(e)}")


@situation.post("/objects/batch-delete")
async def batch_delete_situation_objects(object_ids: List[UUID] = Body(...), db: AsyncSession = Depends(get_db), current_user: User = Depends(get_admin_user)):
    """批量删除态势对象"""
    count = await SituationService.batch_delete(db, object_ids, user=current_user.username if current_user else None)
    return {"message": f"成功删除 {count} 个对象", "count": count}


# ============================================================================
# === 统计信息 ===
# ============================================================================


@situation.get("/statistics", response_model=StatisticsResponse)
async def get_statistics(db: AsyncSession = Depends(get_db), current_user: User = Depends(get_required_user)):
    """获取统计信息"""
    try:
        result = await SituationService.get_statistics(db)
        return result
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取统计信息失败: {str(e)}")


# ============================================================================
# === 批量导入导出 ===
# ============================================================================


@situation.post("/import")
async def import_data(request: ImportRequest, db: AsyncSession = Depends(get_db), current_user: User = Depends(get_admin_user)):
    """
    批量导入数据

    支持格式: json, csv, xml, yaml
    """
    try:
        user = current_user.username if current_user else None

        if request.format == "json":
            result = await SituationService.import_from_json(db, request.data, user)
        elif request.format == "csv":
            result = await SituationService.import_from_csv(db, request.data, user)
        elif request.format == "xml":
            result = await SituationService.import_from_xml(db, request.data, user)
        elif request.format == "yaml":
            result = await SituationService.import_from_yaml(db, request.data, user)
        else:
            raise HTTPException(status_code=400, detail=f"不支持的格式: {request.format}")

        return {"message": "导入完成", "result": result}
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"导入失败: {str(e)}")


@situation.get("/export")
async def export_data(format: str = Query("json", enum=["json", "csv", "xml", "yaml"]), object_type: Optional[ObjectType] = Query(None), db: AsyncSession = Depends(get_db), current_user: User = Depends(get_admin_user)):
    """
    批量导出数据

    支持格式: json, csv, xml, yaml
    """
    try:
        filters = SituationObjectFilter(object_type=object_type) if object_type else None

        if format == "json":
            data = await SituationService.export_to_json(db, filters)
            return {"format": "json", "data": data}
        elif format == "csv":
            data = await SituationService.export_to_csv(db, filters)
            return {"format": "csv", "data": data}
        elif format == "xml":
            data = await SituationService.export_to_xml(db, filters)
            return {"format": "xml", "data": data}
        elif format == "yaml":
            data = await SituationService.export_to_yaml(db, filters)
            return {"format": "yaml", "data": data}
        else:
            raise HTTPException(status_code=400, detail=f"不支持的格式: {format}")
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"导出失败: {str(e)}")


# ============================================================================
# === 类型配置 ===
# ============================================================================


@situation.get("/types")
async def get_object_types(current_user: User = Depends(get_required_user)):
    """获取支持的对象类型列表"""
    types = [
        {"value": "observation_equipment", "label": "观测装备", "icon": "RadarChartOutlined", "color": "#faad14"},
        {"value": "infrastructure", "label": "基础设施", "icon": "BankOutlined", "color": "#1890ff"},
        {"value": "sea_target", "label": "海上目标", "icon": "ShipOutlined", "color": "#52c41a"},
        {"value": "land_target", "label": "陆上目标", "icon": "CarOutlined", "color": "#13c2c2"},
    ]
    return {"types": types}


@situation.get("/deployment-statuses")
async def get_deployment_statuses(current_user: User = Depends(get_required_user)):
    """获取部署状态列表"""
    statuses = [{"value": "已部署", "label": "已部署"}, {"value": "待部署", "label": "待部署"}, {"value": "维护中", "label": "维护中"}, {"value": "退役", "label": "退役"}]
    return {"statuses": statuses}


@situation.get("/equipment-categories")
async def get_equipment_categories(
    object_type: Optional[str] = Query(None, description="对象类型"),
    current_user: User = Depends(get_required_user)
):
    """获取装备类别列表"""
    try:
        logger.info(f"[路由调试] 获取装备类别请求: object_type={object_type}")
        categories = SituationService.get_equipment_categories_by_type(object_type)
        logger.info(f"[路由调试] 获取装备类别成功: {type(categories)}")
        return categories
    except Exception as e:
        logger.error(f"[路由调试] 获取装备类别失败: {e}")
        import traceback
        logger.error(f"[路由调试] 错误堆栈: {traceback.format_exc()}")
        raise HTTPException(status_code=500, detail=f"获取装备类别失败: {str(e)}")


@situation.get("/equipment-category-labels")
async def get_equipment_category_labels(current_user: User = Depends(get_required_user)):
    """获取装备类别标签映射"""
    try:
        from src.situation.schemas import get_equipment_category_labels
        labels = get_equipment_category_labels()
        return labels
    except Exception as e:
        logger.error(f"[路由调试] 获取装备类别标签失败: {e}")
        raise HTTPException(status_code=500, detail=f"获取装备类别标签失败: {str(e)}")


@situation.get("/relationship-types")
async def get_relationship_types(current_user: User = Depends(get_required_user)):
    """获取关系类型列表"""
    try:
        from src.situation.relationship_service import RelationshipService
        relationship_types = RelationshipService.get_relationship_types()
        return relationship_types
    except Exception as e:
        logger.error(f"[路由调试] 获取关系类型失败: {e}")
        import traceback
        logger.error(f"[路由调试] 错误堆栈: {traceback.format_exc()}")
        raise HTTPException(status_code=500, detail=f"获取关系类型失败: {str(e)}")


# ============================================================================
# === 地理空间查询 API ===
# ============================================================================

@situation.post("/geo-query")
async def query_objects_by_area(
    request: dict,
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_required_user)  # 添加普通用户权限即可
):
    """
    根据地图标记范围查询态势对象 - 简化版本用于测试
    """

    logger.info(f"[地理查询] 接收到区域查询请求: {request}")

    try:
        # 验证基本参数
        if not request or "positions" not in request:
            return {
                "success": False,
                "message": "缺少positions参数",
                "data": None,
                "statistics": None,
                "polygon_area": 0.0
            }

        positions = request["positions"]
        if not positions or len(positions) < 3:
            return {
                "success": False,
                "message": "至少需要3个顶点坐标来定义查询区域",
                "data": None,
                "statistics": None,
                "polygon_area": 0.0
            }

        from src.situation.geo_service import GeoService

        # 创建多边形顶点
        polygon_vertices = GeoService.create_polygon_from_positions(positions)
        if not polygon_vertices:
            return {
                "success": False,
                "message": "无效的多边形顶点坐标",
                "data": None,
                "statistics": None,
                "polygon_area": 0.0
            }

        logger.info(f"[地理查询] 创建多边形成功，顶点数: {len(polygon_vertices)}")

        # 查询多边形内的对象
        object_types = request.get("object_types")
        objects_in_area = await GeoService.get_objects_in_polygon(
            db=db,
            polygon_vertices=polygon_vertices,
            object_types=object_types
        )

        # 计算统计信息
        total_objects = sum(len(objs) for objs in objects_in_area.values())
        statistics = {
            "total_count": total_objects,
            "land_targets_count": len(objects_in_area.get("land_targets", [])),
            "sea_targets_count": len(objects_in_area.get("sea_targets", [])),
            "infrastructure_count": len(objects_in_area.get("infrastructure", [])),
            "observation_equipment_count": len(objects_in_area.get("observation_equipment", [])),
            "polygon_vertices_count": len(polygon_vertices)
        }

        # 计算多边形面积
        polygon_area = GeoService.calculate_polygon_area(positions)

        logger.info(f"[地理查询] 查询完成，找到 {total_objects} 个对象，面积: {polygon_area} km²")

        return {
            "success": True,
            "message": f"成功查询到 {total_objects} 个对象",
            "data": objects_in_area,
            "statistics": statistics,
            "polygon_area": polygon_area
        }

    except Exception as e:
        logger.error(f"[地理查询] 查询失败: {e}")
        return {
            "success": False,
            "message": f"地理空间查询失败: {str(e)}",
            "data": None,
            "statistics": None,
            "polygon_area": 0.0
        }


@situation.get("/health")
async def get_database_health(current_user: User = Depends(get_required_user)):
    """获取数据库健康状态"""
    try:
        from src.situation.database import health_check
        health_status = await health_check()
        return {
            "status": "healthy" if health_status["database_connected"] and health_status["table_exists"] else "unhealthy",
            "details": health_status
        }
    except Exception as e:
        logger.error(f"[路由调试] 获取数据库健康状态失败: {e}")
        return {
            "status": "error",
            "error": str(e),
            "timestamp": datetime.utcnow().isoformat()
        }
